<!DOCTYPE html>
<html lang="en">
  
  <head>
    <meta charset="UTF-8">
    <title>
      贪吃蛇
    </title>
    <style>
      .info{width:100%;text-align:center}
      #canvas{position:relative;left:50%;margin-top:100px;margin-left:-400px;height:400px}
      #snakespeed{color:red;font-weight:700}
    </style>
  </head>
  
  <body>
    <canvas id="canvas">
    </canvas>
    <br>
    <div class="info">
      操作： 空格 开始/暂停；方向 上下左右； 当前速度：
      <span id="snakespeed">
        5.00
      </span>
    </div>
    <button onclick="snakeinit()" id="controlbtn" style="display:none">开始游戏</button>
    <script>
      function snakeinit() {
        btn = document.getElementById("controlbtn"),
        "开始游戏" == btn.innerHTML ? (snake.init(), btn.innerHTML = "暂停") : "暂停" == btn.innerHTML ? (snake.timerrun("stop"), btn.innerHTML = "继续") : (btn.innerHTML = "继续") && (snake.timerrun("run"), btn.innerHTML = "暂停")
      }
      var VK_UP = 38,
      VK_DOWN = 40,
      VK_RIGHT = 39,
      VK_LEFT = 37,
      bLeftDown = !1;
      canvas = document.getElementById("canvas"),
      canvas.width = 800,
      canvas.height = 400,
      context = canvas.getContext("2d"),
      context.fillStyle = "#000",
      context.fillRect(0, 0, canvas.width, canvas.height);
      var snake = {
        point: VK_RIGHT,
        size: 10,
        body: [],
        map: [],
        snakecolor: "#0f0",
        inited: !1,
        doudou: [],
        speed: 200,
        init: function() {
          return 1 == snake.inited ? !1 : (snake.inited = !0, snake.body = [], context.fillStyle = "#000", context.fillRect(0, 0, canvas.width, canvas.height), snake.point = VK_RIGHT, context.fillStyle = snake.snakecolor, context.fillRect(1 * snake.size, 1 * snake.size, snake.size, snake.size), context.fillRect(2 * snake.size, 1 * snake.size, snake.size, snake.size), context.fillRect(3 * snake.size, 1 * snake.size, snake.size, snake.size), context.fillRect(4 * snake.size, 1 * snake.size, snake.size, snake.size), context.fillRect(5 * snake.size, 1 * snake.size, snake.size, snake.size), context.fillRect(6 * snake.size, 1 * snake.size, snake.size, snake.size), context.fillRect(7 * snake.size, 1 * snake.size, snake.size, snake.size), snake.body.push([1, 1]), snake.body.push([2, 1]), snake.body.push([3, 1]), snake.body.push([4, 1]), snake.body.push([5, 1]), snake.body.push([6, 1]), snake.body.push([7, 1]), snake.timerrun("run"), snake.initmap(), void snake.createdoudou())
        },
        initmap: function() {
          xlen = canvas.width / snake.size,
          ylen = canvas.height / snake.size;
          for (var e = 0; ylen > e; e++) for (var n = 0; xlen > n; n++) {
            addtag = !0;
            for (var s = snake.body.length - 1; s >= 0; s--) snake.body[s][0] == n && snake.body[s][1] == e && (addtag = !1);
            1 == addtag && snake.map.push([n, e])
          }
        },
        run: function(e, n) {
          return 0 == snake.checkcollision(e, n) ? (snake.timerrun("stop"), snake.inited = !1, alert("you are dead"), document.getElementById("controlbtn").innerHTML = "开始游戏", !1) : (snake.body.push([e, n]), context.fillStyle = snake.snakecolor, context.fillRect(e * snake.size, n * snake.size, snake.size, snake.size), snake.mapupdate("add", e, n), snake.doudou[0] == e && snake.doudou[1] == n ? (snake.createdoudou(), (snake.body.length - 7) % 30 == 0 && snake.changespeed()) : (snake.cleartail(), snake.mapupdate("del", e, n)), void 0)
        },
        mapupdate: function(e, n, s) {
          for (var a = snake.map.length - 1; a >= 0; a--) snake.map[a][0] == n && snake.map[a][1] == s && ("add" == e ? snake.map.push([n, s]) : snake.map.splice(a, 1))
        },
        cleartail: function() {
          tail = snake.body.shift(),
          context.fillStyle = "#000",
          context.fillRect(tail[0] * snake.size, tail[1] * snake.size, snake.size, snake.size)
        },
        timerrun: function(e) {
          "run" == e ? timerrun = setInterval(snake.callrun, snake.speed) : clearInterval(timerrun)
        },
        callrun: function() {
          var e = snake.body[snake.body.length - 1];
          snake.point == VK_UP ? snake.run(e[0], e[1] - 1) : snake.point == VK_DOWN ? snake.run(e[0], e[1] + 1) : snake.point == VK_RIGHT ? snake.run(e[0] + 1, e[1]) : snake.point == VK_LEFT && snake.run(e[0] - 1, e[1])
        },
        pointrun: function(e) {
          e == VK_UP && snake.point != VK_DOWN ? (snake.point = e, snake.callrun(), snake.timerrun("stop"), snake.timerrun("run")) : e == VK_DOWN && snake.point != VK_UP ? (snake.point = e, snake.callrun(), snake.timerrun("stop"), snake.timerrun("run")) : e == VK_RIGHT && snake.point != VK_LEFT ? (snake.point = e, snake.callrun(), snake.timerrun("stop"), snake.timerrun("run")) : e == VK_LEFT && snake.point != VK_RIGHT && (snake.point = e, snake.callrun(), snake.timerrun("stop"), snake.timerrun("run"))
        },
        createdoudou: function() {
          return newdoudou = snake.map[Math.floor(Math.random() * snake.map.length)],
          void 0 == newdoudou ? (alert("you are winner"), snake.timerrun("stop"), snake.inited = !1, document.getElementById("controlbtn").innerHTML = "开始游戏", !1) : (x = newdoudou[0], y = newdoudou[1], context.fillStyle = snake.snakecolor, context.fillRect(x * snake.size, y * snake.size, snake.size, snake.size), void(snake.doudou = [x, y]))
        },
        checkcollision: function(e, n) {
          if (e * snake.size < 0 || n * snake.size < 0 || n * snake.size > canvas.height - 1 || e * snake.size > canvas.width - 1) return ! 1;
          for (var s = snake.body.length - 1; s >= 0; s--) if (snake.body[s][0] == e && snake.body[s][1] == n) return ! 1;
          return ! 0
        },
        changespeed: function() {
          snake.speed -= 10,
          snake.timerrun("stop"),
          snake.timerrun("run"),
          document.getElementById("snakespeed").innerHTML = (1e3 / snake.speed).toFixed(2)
        }
      };
      document.onkeydown = function(e) {
        e.keyCode != VK_UP && e.keyCode != VK_DOWN && e.keyCode != VK_RIGHT && e.keyCode != VK_LEFT || bLeftDown || (bLeftDown = !0)
      },
      document.onkeyup = function(e) {
        32 == e.keyCode ? snakeinit() : 1 == snake.inited && 107 == e.keyCode ? snake.changespeed() : 1 == snake.inited && snake.pointrun(e.keyCode)
      };
    </script>
  </body>

</html>